/*******************************************************************************
 * Copyright (c) 2006 CEA List.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     CEA List - initial API and implementation
 *******************************************************************************/
package com.cea.papyrus.core.tabbedproperties.composite;

import org.eclipse.gef.commands.CommandStack;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.views.properties.tabbed.ITabbedPropertyConstants;
import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetWidgetFactory;

import com.cea.papyrus.core.PapyrusPlugin;
import com.cea.papyrus.umlutils.Element;

/**
 * Base class for a complex section composite. This composite has a label, a
 * text that describes an element, and two buttons on the side of the
 * table to add a string representing an element, or remove element of the text
 * 
 * @author Arnaud CUCCURU
 */
public abstract class DecoratedTextComposite implements ISectionComposite {

	/**
	 * Image for the add element button.
	 */
	final protected static Image NEW_ELEMENT_IMG = PapyrusPlugin.getImage(PapyrusPlugin.PAPYRUS_ICONS_16x16+"Add_16x16.gif");
	
	/**
	 * Image for the delete element button.
	 */
	final protected static Image DELETE_ELEMENT_IMG = PapyrusPlugin.getImage(PapyrusPlugin.PAPYRUS_ICONS_16x16+"Delete_16x16.gif");
	

	// child composites for the table composite
	
	/**
	 * main composite of this complex composite.
	 */
	protected Composite composite;
	
	/**
	 * Label next to text.
	 */
	protected CLabel label;
	
	/**
	 * Table that displays a property for the current element.
	 */
	protected Text text;
	
	/**
	 * Add button.
	 */ 
	protected Button addButton;
	
	/**
	 * Remove Button.
	 */ 
	protected Button removeButton;
	
	
	// listeners for buttons
	/**
	 * Listener for the add button.
	 */
	protected MouseListener addButtonlistener;
	
	/**
	 * Listener for the delete button.
	 */
	protected MouseListener removeButtonlistener;
	
	/**
	 * Listener for the text Text 
	 */
	protected MouseListener textTextListener ;
	
	/**
	 * Element selected in the Papyrus modeler.
	 */
	protected Element element;
	
	
	// Construction parameters for the composite
	/**
	 * text of the label.
	 */
	protected String name;
	
	/**
	 * returns the element that is selected in Papyrus tool, for which
	 * properties are displayed in the property section.
	 * 
	 * @return the element
	 */
	public Element getElement() {
		return element;
	}

	/**
	 * Sets the element that holds property displyed in property section.
	 * 
	 * @param element the element to set
	 */
	public void setElement(Element element) {
		this.element = element;
	}
	
	/**
	 * Constructor.
	 * 
	 * @param name text of the Label on the top left of this composite
	 */
	public DecoratedTextComposite(String name) {
		this.name = name;
		this.addButtonlistener = new AddButtonlistener();
		this.removeButtonlistener = new RemoveButtonlistener();
		this.textTextListener = new TextTextListener() ;
	}
	
	/**
	 * Constructor.
	 * 
	 * @param name text of the Label on the top left of this composite
	 */
	public DecoratedTextComposite() {
		this.addButtonlistener = new AddButtonlistener();
		this.removeButtonlistener = new RemoveButtonlistener();
		this.textTextListener = new TextTextListener() ;
	}
	
	/**
	 * {@inheritDoc}
	 */
	public Composite createContent(Composite parent,
			TabbedPropertySheetWidgetFactory factory) {
		composite = factory.createFlatFormComposite(parent);

		FormData data;

//		 Create label
		label = factory.createCLabel(composite, name+":", SWT.NONE);
		label.setLayout(new FormLayout());
		data = new FormData();
		data.top  = new FormAttachment(0, 0);
		data.left = new FormAttachment(0, 0);
		label.setLayoutData(data);

		// Create delete button
		removeButton = factory.createButton(composite, "",  SWT.PUSH);
		removeButton.setVisible(true);
		removeButton.setImage(DELETE_ELEMENT_IMG);
		removeButton.setToolTipText("Delete selected element");
		data = new FormData();
		data.top  = new FormAttachment(0, 0);
		data.right = new FormAttachment(100, -ITabbedPropertyConstants.HSPACE);
		removeButton.setLayoutData(data);
		removeButton.addMouseListener(removeButtonlistener);
		
		// create add button
		addButton = factory.createButton(composite, "", SWT.PUSH);
		addButton.setVisible(true);
		addButton.setImage(NEW_ELEMENT_IMG);
		addButton.setToolTipText("Add an element");
		data = new FormData();
		// data.top   = new FormAttachment(label, ITabbedPropertyConstants.HSPACE);
		data.top  = new FormAttachment(0, 0);
		data.right = new FormAttachment(removeButton, -ITabbedPropertyConstants.HSPACE);
		addButton.setLayoutData(data);
		addButton.addMouseListener(addButtonlistener);
		
		// Create text
		text = factory.createText(composite, "");
		text.setVisible(true);
		text.setEditable(false);
		data = new FormData();
//		data.width = 50 ;
//		data.height = 100;
		data.left   = new FormAttachment(label, -ITabbedPropertyConstants.HSPACE);
		data.right  = new FormAttachment(addButton, -ITabbedPropertyConstants.HSPACE);
		data.top    = new FormAttachment(0, ITabbedPropertyConstants.VSPACE);
		text.setLayoutData(data);
		text.addMouseListener(textTextListener) ;
				
		return composite;
	}

	/**
	 * {@inheritDoc}
	 */
	public void refresh() {
	}
	
	/**
	 * Sets the layout data to the main composite of this complex element.
	 * 
	 * @param data the new LayoutData
	 */
	public void setLayoutData(Object data) {
		composite.setLayoutData(data);
	}
	
	/**
	 * get the sub composite
	 * @return the sub composite
	 */
	public Composite getMainComposite() {
		return composite;
	}
	
	/**
	 * Returns the CommmandStack of the current editor.
	 * 
	 * @return the CommmandStack of the current editor
	 */
	public CommandStack getCommandStack() {
		return (CommandStack)getActiveEditor().getAdapter(CommandStack.class);
	}
	
	/**
	 * Returns the current Editor.
	 * 
	 * @return the current editor
	 */
	public IEditorPart getActiveEditor() {
		return PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor(); 
	}
	
	/**
	 * action executed when the add button is pressed.
	 */
	public abstract void addButtonPressed() ;
	
	/**
	 * action executed when the remove button is pressed.
	 */
	public abstract void removeButtonPressed() ;
	
	
	/**
	 * action executed when a table item is edited.
	 * 
	 * @param item 
	 */
	public abstract void editText() ;
	
	/**
	 * Listener for the Add Button
	 * Specific behavior is implemented in {@link DecoratedTextComposite#addButtonPressed()}.
	 * 
	 * @author Remi SCHNEKENBURGER
	 */
	private class AddButtonlistener implements MouseListener {
		
		/**
		 * {@inheritDoc}
		 */
		public void mouseDoubleClick(MouseEvent e) {
			// do nothing
		}
		
		/**
		 * {@inheritDoc}
		 */
		public void mouseDown(MouseEvent e) {
			// do nothing
		}
		
		/**
		 * {@inheritDoc}
		 */
		public void mouseUp(MouseEvent e) {
			addButtonPressed();
			refresh();
		}
	}

	/**
	 * Listener for the Remove Button
	 * Specific behavior is implemented in {@link DecoratedTextComposite#removeButtonPressed()}.
	 * 
	 * @author Remi SCHNEKENBURGER
	 */
	private class RemoveButtonlistener implements MouseListener {
		
		/**
		 * {@inheritDoc}
		 */
		public void mouseDoubleClick(MouseEvent e) {
			// do nothing
		}
		
		/**
		 * {@inheritDoc}
		 */
		public void mouseDown(MouseEvent e) {
			// do nothing
		}
		
		/**
		 * {@inheritDoc}
		 */
		public void mouseUp(MouseEvent e) {
			removeButtonPressed();
			refresh();
		}
	}

	/**
	 * Listener for the Remove Button
	 * Specific behavior is implemented in {@link DecoratedTextComposite#removeButtonPressed()}.
	 * 
	 * @author Remi SCHNEKENBURGER
	 */
	private class TextTextListener implements MouseListener {
		
		/**
		 * {@inheritDoc}
		 */
		public void mouseDoubleClick(MouseEvent e) {
			editText() ;
			refresh() ;
		}
		
		/**
		 * {@inheritDoc}
		 */
		public void mouseDown(MouseEvent e) {
			// do nothing
		}
		
		/**
		 * {@inheritDoc}
		 */
		public void mouseUp(MouseEvent e) {
			// do nothing

		}
	}
	
	/**
	 * removes listeners from buttons.
	 */
	public void dispose() {
		if(addButton!=null && !addButton.isDisposed())
			addButton.removeMouseListener(addButtonlistener);
		if(removeButton!=null && !removeButton.isDisposed())
			removeButton.removeMouseListener(removeButtonlistener);
	}
}
